package com.jdd.modules.people.controller;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jdd.common.api.vo.Result;
import com.jdd.common.constant.CacheConstant;
import com.jdd.common.system.query.QueryGenerator;
import com.jdd.common.system.vo.LoginUser;
import com.jdd.common.util.LoginUserUtils;
import com.jdd.common.util.RedisUtil;
import com.jdd.common.util.ResultGenerator;
import com.jdd.common.util.excel.entity.params.ExportParams;
import com.jdd.common.util.excel.web.entity.vo.NormalExcelConstants;
import com.jdd.common.util.excel.web.view.EasypoiSingleExcelView;
import com.jdd.dao.entity.SysDepartArea;
import com.jdd.dao.entity.TArea;
import com.jdd.dao.entity.TProject;
import com.jdd.dao.mapper.TAreaMapper;
import com.jdd.dao.mapper.TProjectMapper;
import com.jdd.dao.service.ISysDepartAreaService;
import com.jdd.dao.service.TAreaService;
import com.jdd.dao.service.TProjectService;
import com.jdd.modules.device.entity.TDevice;
import com.jdd.modules.device.service.TDeviceService;
import com.jdd.modules.people.entity.Bind;
import com.jdd.modules.people.model.TProjectTreeModel;
import com.jdd.modules.people.vo.GetProjectListReqVo;
import com.jdd.modules.projectusertype.entity.ProjectUserType;
import com.jdd.modules.projectusertype.service.IProjectUserTypeService;
import com.jdd.modules.system.entity.SysUserDepart;
import com.jdd.modules.system.service.ISysUserDepartService;
import com.jdd.utils.SnowFlakeUtil;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author zly
 * @since 2022-01-21
 */
@Slf4j
@RestController("TProjectController")
@RequestMapping("/project")
public class TProjectController {

    @Resource
    private ISysDepartAreaService sysAreaService;

    @Resource
    private ISysUserDepartService sysUserDepartService;

    @Resource
    private TAreaService tAreaService;

    @Resource
    private ISysDepartAreaService areaService;

    @Resource
    private TProjectService tProjectService;

    @Resource
    private TProjectMapper tProjectMapper;

    @Resource
    private TAreaMapper tAreaMapper;

    @Resource
    private IProjectUserTypeService projectUserTypeService;

    @Resource
    private RedisUtil redisUtil;
    @Resource
    TDeviceService deviceService;


    @RequestMapping(value = "/queryTreeList", method = RequestMethod.GET)
    public Result<List<TProjectTreeModel>> queryTreeList() {
        Result<List<TProjectTreeModel>> result = new Result<>();
        List<TProjectTreeModel> treeModels = new ArrayList<>();
        try {
            List<TProjectTreeModel> list = tProjectService.queryTreeList();
            result.setResult(list);
            List<TProject> projects = tProjectService.list();
            for (TProject project : projects) {
                treeModels.add(new TProjectTreeModel(project));
            }
            result.setResult(treeModels);
            result.setSuccess(true);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return result;
    }

    @RequestMapping(value = "/getAreaTree", method = RequestMethod.GET)
    public Result<List<TProjectTreeModel>> getAreaTree() {
        Result<List<TProjectTreeModel>> result = new Result<>();
        List<TProjectTreeModel> treeModels = new ArrayList<>();
        try {
            LambdaQueryWrapper<TProject> tProjectLambdaQueryWrapper = new LambdaQueryWrapper<>();
            tProjectLambdaQueryWrapper.in(TProject::getId,LoginUserUtils.getProjectCodeList());
            List<TProject> projects = tProjectService.list(tProjectLambdaQueryWrapper);
            for (TProject project : projects) {
                treeModels.add(new TProjectTreeModel(project));
            }
            result.setResult(treeModels);
            result.setSuccess(true);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return result;
    }

    @RequestMapping(value = "/getAreaTreeById", method = RequestMethod.GET)
    public Result<List<TProjectTreeModel>> getAreaTreeById(String id) {
        Result<List<TProjectTreeModel>> result = new Result<>();
        List<TProjectTreeModel> treeModels = new ArrayList<>();
        try {
            TProject project = tProjectService.getById(id);
            if (project!=null){
                treeModels.add(new TProjectTreeModel(project));
            }
            result.setResult(treeModels);
            result.setSuccess(true);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return result;
    }

    /*传入项目id，返回该项目id下的子节点*/
    @GetMapping("/getChildren")
    public Result<List<TProjectTreeModel>> getChildren(@RequestParam(name = "id") String id) {
        List<TProjectTreeModel> tProjectTreeModels = new ArrayList<>();
        LambdaQueryWrapper<TArea> tAreaLambdaQueryWrapper = new LambdaQueryWrapper<>();
        tAreaLambdaQueryWrapper.eq(TArea::getParentId, id);
        List<TArea> areaList = tAreaService.list(tAreaLambdaQueryWrapper);
        for (TArea tArea : areaList) {
            tProjectTreeModels.add(new TProjectTreeModel(tArea));
        }
        return ResultGenerator.genSuccessResult(tProjectTreeModels);
    }

    /*传入项目id，返回该项目id下的子节点*/
    @GetMapping("/getChildrenWithDevice")
    public Result<List<TProjectTreeModel>> getChildrenWithTDevice(@RequestParam(name = "id") String id) {
        List<TProjectTreeModel> tProjectTreeModels = new ArrayList<>();
        LambdaQueryWrapper<TArea> tAreaLambdaQueryWrapper = new LambdaQueryWrapper<>();
        tAreaLambdaQueryWrapper.eq(TArea::getParentId, id);
        List<TArea> areaList = tAreaService.list(tAreaLambdaQueryWrapper);
        for (TArea tArea : areaList) {
            tProjectTreeModels.add(new TProjectTreeModel(tArea));
            LambdaQueryWrapper<TDevice> deviceLambdaQueryWrapper = new LambdaQueryWrapper<>();
            deviceLambdaQueryWrapper.eq(TDevice::getAreaId, id);
            deviceLambdaQueryWrapper.isNull(TDevice::getBuildingId);
            List<TDevice> deviceList = deviceService.list(deviceLambdaQueryWrapper);
            for (TDevice device : deviceList) {
                tProjectTreeModels.add(new TProjectTreeModel(device, tArea));
            }
        }
        return ResultGenerator.genSuccessResult(tProjectTreeModels);
    }


    @RequestMapping(value = "/list", method = RequestMethod.GET)
    public Result<IPage<TProject>> queryPageList(TProject tProject, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                 @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) {
        Result<IPage<TProject>> result = new Result<IPage<TProject>>();
        if (StringUtils.isNotBlank(tProject.getName())) {
            tProject.setName("*" + tProject.getName() + "*");
        }

        QueryWrapper<TProject> queryWrapper = QueryGenerator.initQueryWrapper(tProject, req.getParameterMap());
        Page<TProject> page = new Page<TProject>(pageNo, pageSize);
        IPage<TProject> pageList = tProjectService.page(page, queryWrapper);
        result.setSuccess(true);
        result.setResult(pageList);
        return result;
    }

    @RequestMapping(value = "/noBindList", method = RequestMethod.GET)
    public Result<Page<TProject>> queryPageNoBindList(TProject tProject, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                      @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) {
        Result<Page<TProject>> result = new Result<Page<TProject>>();
        QueryWrapper<TProject> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(tProject.getName())) {
            queryWrapper.like("name", tProject.getName());
        }
        // 查询条件为空的
        queryWrapper.isNull("sys_area_id");
        List<String> projectCodeList = LoginUserUtils.getProjectCodeList();
        if (projectCodeList != null && projectCodeList.size() > 0) {
            queryWrapper.in("id", LoginUserUtils.getProjectCodeList());
        } else {
            return result;
        }


        Page<TProject> page = new Page<TProject>(pageNo, pageSize);
        tProjectMapper.selectPage(page, queryWrapper);
        result.setSuccess(true);
        result.setResult(page);
        return result;
    }

    @PostMapping("/add")
    public Result add(@RequestBody TProject tProject, HttpServletRequest req) {
        String projectCode = "";
        tProject.setId(SnowFlakeUtil.getId());
        tProject.setSysProjectCode(LoginUserUtils.getOrgCode());
        redisUtil.del(CacheConstant.LOGIN_USER_PROJECT_PERMISSION_CACHE + LoginUserUtils.getLoginUser().getId());
        tProjectService.save(tProject);
        //新增项目并新增默认区域
        TArea tArea = new TArea();
        tArea.setName("默认区域");
        String id = SnowFlakeUtil.getId();
        tArea.setId(id);
        tArea.setParentId(tProject.getId());
        tArea.setProjectId(tProject.getId());
        //新增项目中的人员类型
        ProjectUserType projectUserType = new ProjectUserType();
        projectUserType.setTypeName("户主");
        String userTypeId = SnowFlakeUtil.getId();
        projectUserType.setId(userTypeId);
        projectUserType.setProjectName(tProject.getName());
        projectUserType.setProjectId(tProject.getId());
        projectUserType.setTypeNum("1");
        projectUserTypeService.save(projectUserType);
        /*获取父节点的编号*/
        TProject tProject1 = tProjectService.getById(tProject.getId());
        Integer code = tProject1.getCode();
        tArea.setParentCode("D" + code);
        tArea.setSysProjectCode(LoginUserUtils.getLoginUser().getOrgCode());
        tAreaService.save(tArea);
        return ResultGenerator.genSuccessResult(tProject);
    }

    /*绑定项目*/
    @PostMapping("/bind")
    public Result bind(@RequestBody Bind bind) {
        log.info("bind:{}", bind);
//        if (bind.getAreaName()==null){
        SysDepartArea area = areaService.getById(bind.getParentId());
        if (bind.getParentId() != null) {
            List<String> userList = new ArrayList<>();
            /*获取需要绑定的user*/
            getUser(bind.getParentId(), userList);
            for (String userId : userList) {
                for (String projectId : bind.getProjectIds()) {
                    /*项目的绑定*/
                    SysUserDepart sysUserDepart = new SysUserDepart();
                    sysUserDepart.setUserId(userId);
                    sysUserDepart.setDepId(projectId);
                    sysUserDepart.setType(0);
                    sysUserDepartService.save(sysUserDepart);
                }
            }
        }
        if (area != null) {
            tProjectService.bind(bind.getProjectIds(), bind.getParentId(), area.getName(), area.getId());
        }

        return ResultGenerator.genSuccessResult("绑定成功");
    }

    /*查找父级目录下的人员并封装*/
    public void getUser(String parentId, List<String> userIds) {
        QueryWrapper<SysDepartArea> sysDepartAreaQueryWrapper = new QueryWrapper<>();
        sysDepartAreaQueryWrapper.eq("id", parentId);
        SysDepartArea sysAreaServiceOne = sysAreaService.getOne(sysDepartAreaQueryWrapper);
        QueryWrapper<SysUserDepart> sysUserDepartQueryWrapper = new QueryWrapper<>();
        sysUserDepartQueryWrapper.eq("dep_id", parentId);
        List<SysUserDepart> list = sysUserDepartService.list(sysUserDepartQueryWrapper);
        for (SysUserDepart sysUserDepart : list) {
            if (!userIds.contains(sysUserDepart.getUserId())) {
                userIds.add(sysUserDepart.getUserId());
            }
        }
        if (sysAreaServiceOne.getParentId() != null) {
            getUser(sysAreaServiceOne.getParentId(), userIds);
        }
    }

    /*解绑*/
    @DeleteMapping("/removeBind")
    public Result removeBind(@RequestParam(name = "id", required = true) String id) {
        TProject tProject = tProjectService.getById(id);
        QueryWrapper<SysUserDepart> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("dep_id", tProject.getId());
        List<SysUserDepart> list = sysUserDepartService.list(queryWrapper);
        if (list != null && list.size() > 0) {
            return ResultGenerator.genFailResult("解绑失败，当前项目下存在用户");
        }

        tProjectService.removeBind(id);

        return ResultGenerator.genSuccessResult("解绑成功");
    }

    @PostMapping("/deleteById/{id}")
    public Result deleteById(@PathVariable String id) {
        tProjectService.removeById(id);
        return ResultGenerator.genSuccessResult(id);
    }

    @ApiOperation(value = "通过id删除", notes = "通过id删除")
    @DeleteMapping(value = "/delete")
    public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
        try {

            //删除区域
            tProjectService.removeById(id);
        } catch (Exception e) {
            return ResultGenerator.genFailResult("删除失败");
        }
        return ResultGenerator.genSuccessResult("删除成功");
    }

    @ApiOperation(value = "通过id删除", notes = "通过id删除")
    @DeleteMapping(value = "/deleteBatch")
    public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
        if (ids == null || "".equals(ids.trim())) {
            return ResultGenerator.genFailResult("参数有误");
        }
        List<String> list = Arrays.asList(ids.split(","));

        try {
            tProjectService.removeByIds(list);
        } catch (Exception e) {
            return ResultGenerator.genFailResult("删除失败");
        }
        return ResultGenerator.genSuccessResult("删除成功");
    }

    @PostMapping("/updateById")
    public Result updateById(@RequestBody TProject tProject) {
        if (tProject.getId() == null) {
            return ResultGenerator.genFailResult("id为空，修改失败");
        }
        TProject project = tProjectService.getById(tProject.getId());
        String deviceParentCode = "D"+project.getCode();
        deviceService.updateDeviceAlias(deviceParentCode,0,"",tProject.getName());
        tProjectService.updateById(tProject);
        return ResultGenerator.genSuccessResult(tProject);
    }

    @GetMapping("/selectById/{id}")
    public Result selectById(@PathVariable String id) {
        TProject tProject = tProjectService.getById(id);
        return ResultGenerator.genSuccessResult(tProject);
    }

    @PostMapping("/getProjectList")
    public Result getProjectList(@RequestBody @Valid GetProjectListReqVo reqVo) {
        Page<TProject> pageTemp = new Page<>(reqVo.getPageNo(), reqVo.getPageSize());
        LoginUser loginUser = LoginUserUtils.getLoginUser();
        if (CollUtil.isEmpty(loginUser.getProjectCodes())) {
            return Result.ok();
        }
        QueryWrapper<TProject> wrapper = getWrapper(reqVo);
        wrapper.lambda().in(TProject::getId, loginUser.getProjectCodes());
        IPage<TProject> page = tProjectService.page(pageTemp, wrapper);
        return ResultGenerator.genSuccessResult(page);
    }

    @GetMapping("/getProjectListAll")
    public Result getProjectListAll() {
        QueryWrapper<TProject> wrapper = new QueryWrapper<>();
//        wrapper.eq("status", 1);
        List<TProject> list = null;
        List<String> projectCodes = LoginUserUtils.getLoginUser().getProjectCodes();
        if (projectCodes != null && projectCodes.size() > 0) {
            wrapper.in("id", projectCodes);
            wrapper.orderByDesc("create_time");
            list = tProjectService.list(wrapper);
        }
        return ResultGenerator.genSuccessResult(list);
    }


    /**
     * 导出excel
     *
     * @param request
     * @param response
     */
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response, GetProjectListReqVo reqVo) {
        QueryWrapper<TProject> wrapper = getWrapper(reqVo);
        ModelAndView mv = new ModelAndView(new EasypoiSingleExcelView());
        List<TProject> pageList = tProjectService.list(wrapper);
        //导出文件名称
        mv.addObject(NormalExcelConstants.FILE_NAME, "项目列表");
        mv.addObject(NormalExcelConstants.CLASS, TProject.class);
        mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("项目列表数据", "导出信息"));
        mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
        return mv;
    }

    public QueryWrapper<TProject> getWrapper(GetProjectListReqVo reqVo) {
        QueryWrapper<TProject> wrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(reqVo.getName())) {
            wrapper.like("name", reqVo.getName());

        }
        if (!StringUtils.isEmpty(reqVo.getProjectType())) {
            wrapper.eq("project_type", reqVo.getProjectType());
        }
        if (reqVo.getProjectManager() != null) {
            wrapper.like("project_manager", reqVo.getProjectManager());
        }
        wrapper.orderByAsc("status").orderByDesc("create_time");
        return wrapper;
    }
}
